package com.lxxie.util;

import com.alibaba.fastjson.JSON;
import org.apache.tomcat.util.buf.HexUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by kuangxiaoguo on 16/9/11.
 * <p>
 * DES加密工具类
 */
public class DESUtil {
        
        private final static Logger _logger = LoggerFactory.getLogger(DESUtil.class);
        
        private final static String KEY = "91e63e5758dad5ea";
        
        private static byte[] KEY_BYTE;
        
        private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
        
        /**
         * 生成密钥
         */
        public static byte[] initKey() {
                try {
                        //KeyGenerator 密钥生成器
                        KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
                        //初始化密钥生成器
                        keyGenerator.init(56);
                        //生成密钥
                        SecretKey secretKey = keyGenerator.generateKey();
                        return secretKey.getEncoded();
                } catch (Exception e) {
                        _logger.error("initKey error: ", e);
                }
                return null;
        }
        
        /**
         * DES加密
         *
         * @param data 需要加密的数据
         * @return 加密后获取的字节数组
         */
        public static byte[] encrypt(byte[] data) {
                //恢复密钥
                SecretKey secretKey = new SecretKeySpec(KEY_BYTE, "DES");
                IvParameterSpec zeroIv = new IvParameterSpec(iv);
                try {
                        //Cipher完成加密或解密工作
                        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
                        //根据密钥对Cipher进行初始化 ENCRYPT_MODE, DECRYPT_MODE
                        cipher.init(Cipher.ENCRYPT_MODE, secretKey,zeroIv);
                        //加密
                        return cipher.doFinal(data);
                } catch (Exception e) {
                        _logger.error("encrypt error: ", e);
                }
                return null;
        }
        
        /**
         * DES解密
         */
        /**
         * @param data 密文对应的字节数组
         * @return 解密后的字节数组
         */
        public static byte[] decrypt(byte[] data) {
                SecretKey secretKey = new SecretKeySpec(KEY_BYTE, "DES");
                IvParameterSpec zeroIv = new IvParameterSpec(iv);
                try {
                        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
                        cipher.init(Cipher.DECRYPT_MODE, secretKey,zeroIv);
                        return cipher.doFinal(data);
                } catch (Exception e) {
                        _logger.error("decrypt error: ", e);
                }
                return null;
        }
        
        static {
                KEY_BYTE = HexUtils.fromHexString(KEY);
        }
        
        public static String decryptDES(String encryptString, String encryptKey)
                throws Exception {
                IvParameterSpec zeroIv = new IvParameterSpec(iv);
                SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
                Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
                byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
                return new String(Base64Utils.encode(encryptedData));
        }
        
        
        public static void main(String[] args) throws Exception {
                Map<String,String> map = new HashMap<>();
                map.put("username","杨欣欣");
                map.put("password","123543");
                String str = JSON.toJSONString(map);
                byte[] enBs = DESUtil.encrypt(str.getBytes("UTF-8"));
        
                System.out.println(str);
                System.out.println(Base64Utils.encodeToString(enBs));
                
        }
}
